/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.configuration.beanutils;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.configuration.ConfigurationRuntimeException;
import junit.framework.TestCase;
/**
* Test class for BeanHelper.
*
* @since 1.3
* @author Oliver Heger
* @version $Id: TestBeanHelper.java 570462 2007-08-28 15:56:49Z oheger $
*/
public class TestBeanHelper extends TestCase
{
/** Constant for the name of the test bean factory. */
private static final String TEST_FACTORY = "testFactory";
/**
* Stores the default bean factory. Because this is a static field in
* BeanHelper it is temporarily stored and reset after the tests.
*/
private BeanFactory tempDefaultBeanFactory;
protected void setUp() throws Exception
{
super.setUp();
tempDefaultBeanFactory = BeanHelper.getDefaultBeanFactory();
deregisterFactories();
}
protected void tearDown() throws Exception
{
deregisterFactories();
// Reset old default bean factory
BeanHelper.setDefaultBeanFactory(tempDefaultBeanFactory);
super.tearDown();
}
/**
* Removes all bean factories that might have been registered during a test.
*/
private void deregisterFactories()
{
for (Iterator it = BeanHelper.registeredFactoryNames().iterator(); it
.hasNext();)
{
BeanHelper.deregisterBeanFactory((String) it.next());
}
assertTrue("Remaining registered bean factories", BeanHelper
.registeredFactoryNames().isEmpty());
}
/**
* Tests registering a new bean factory.
*/
public void testRegisterBeanFactory()
{
assertTrue("List of registered factories is not empty", BeanHelper
.registeredFactoryNames().isEmpty());
BeanHelper.registerBeanFactory(TEST_FACTORY, new TestBeanFactory());
assertEquals("Wrong number of registered factories", 1, BeanHelper
.registeredFactoryNames().size());
assertTrue("Test factory is not contained", BeanHelper
.registeredFactoryNames().contains(TEST_FACTORY));
}
/**
* Tries to register a null factory. This should cause an exception.
*/
public void testRegisterBeanFactoryNull()
{
try
{
BeanHelper.registerBeanFactory(TEST_FACTORY, null);
fail("Could register null factory!");
}
catch (IllegalArgumentException iex)
{
// ok
}
}
/**
* Tries to register a bean factory with a null name. This should cause an
* exception.
*/
public void testRegisterBeanFactoryNullName()
{
try
{
BeanHelper.registerBeanFactory(null, new TestBeanFactory());
fail("Could register factory with null name!");
}
catch (IllegalArgumentException iex)
{
// ok
}
}
/**
* Tests to deregister a bean factory.
*/
public void testDeregisterBeanFactory()
{
assertNull("deregistering non existing factory", BeanHelper
.deregisterBeanFactory(TEST_FACTORY));
assertNull("deregistering null factory", BeanHelper
.deregisterBeanFactory(null));
BeanFactory factory = new TestBeanFactory();
BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
assertSame("Could not deregister factory", factory, BeanHelper
.deregisterBeanFactory(TEST_FACTORY));
assertTrue("List of factories is not empty", BeanHelper
.registeredFactoryNames().isEmpty());
}
/**
* Tests whether the default bean factory is correctly initialized.
*/
public void testGetDefaultBeanFactory()
{
assertSame("Incorrect default bean factory",
DefaultBeanFactory.INSTANCE, tempDefaultBeanFactory);
}
/**
* Tests setting the default bean factory to null. This should caus an
* exception.
*/
public void testSetDefaultBeanFactoryNull()
{
try
{
BeanHelper.setDefaultBeanFactory(null);
fail("Could set default bean factory to null!");
}
catch (IllegalArgumentException iex)
{
// ok
}
}
/**
* Tests initializing a bean.
*/
public void testInitBean()
{
BeanHelper.setDefaultBeanFactory(new TestBeanFactory());
TestBeanDeclaration data = setUpBeanDeclaration();
TestBean bean = new TestBean();
BeanHelper.initBean(bean, data);
checkBean(bean);
}
/**
* Tests initializing a bean when the bean declaration does not contain any
* data.
*/
public void testInitBeanWithNoData()
{
TestBeanDeclaration data = new TestBeanDeclaration();
TestBean bean = new TestBean();
BeanHelper.initBean(bean, data);
assertNull("Wrong string property", bean.getStringValue());
assertEquals("Wrong int property", 0, bean.getIntValue());
assertNull("Buddy was set", bean.getBuddy());
}
/**
* Tries to initialize a bean with a bean declaration that contains an
* invalid property value. This should cause an exception.
*/
public void testInitBeanWithInvalidProperty()
{
TestBeanDeclaration data = setUpBeanDeclaration();
data.getBeanProperties().put("nonExistingProperty", Boolean.TRUE);
try
{
BeanHelper.initBean(new TestBean(), data);
fail("Could initialize non existing property!");
}
catch (ConfigurationRuntimeException cex)
{
// ok
}
}
/**
* Tests creating a bean. All necessary information is stored in the bean
* declaration.
*/
public void testCreateBean()
{
TestBeanFactory factory = new TestBeanFactory();
BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
TestBeanDeclaration data = setUpBeanDeclaration();
data.setBeanFactoryName(TEST_FACTORY);
data.setBeanClassName(TestBean.class.getName());
checkBean((TestBean) BeanHelper.createBean(data, null));
assertNull("A parameter was passed", factory.parameter);
}
/**
* Tests creating a bean when no bean declaration is provided. This should
* cause an exception.
*/
public void testCreateBeanWithNullDeclaration()
{
try
{
BeanHelper.createBean(null);
fail("Could create bean with null declaration!");
}
catch (IllegalArgumentException iex)
{
// ok
}
}
/**
* Tests creating a bean. The bean's class is specified as the default class
* argument.
*/
public void testCreateBeanWithDefaultClass()
{
BeanHelper.registerBeanFactory(TEST_FACTORY, new TestBeanFactory());
TestBeanDeclaration data = setUpBeanDeclaration();
data.setBeanFactoryName(TEST_FACTORY);
checkBean((TestBean) BeanHelper.createBean(data, TestBean.class));
}
/**
* Tests creating a bean when the bean's class is specified as the default
* class of the bean factory.
*/
public void testCreateBeanWithFactoryDefaultClass()
{
TestBeanFactory factory = new TestBeanFactory();
factory.supportsDefaultClass = true;
BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
TestBeanDeclaration data = setUpBeanDeclaration();
data.setBeanFactoryName(TEST_FACTORY);
checkBean((TestBean) BeanHelper.createBean(data, null));
}
/**
* Tries to create a bean when no class is provided. This should cause an
* exception.
*/
public void testCreateBeanWithNoClass()
{
BeanHelper.registerBeanFactory(TEST_FACTORY, new TestBeanFactory());
TestBeanDeclaration data = setUpBeanDeclaration();
data.setBeanFactoryName(TEST_FACTORY);
try
{
BeanHelper.createBean(data, null);
fail("Could create bean without class!");
}
catch (ConfigurationRuntimeException cex)
{
// ok
}
}
/**
* Tries to create a bean with a non existing class. This should cause an
* exception.
*/
public void testCreateBeanWithInvalidClass()
{
BeanHelper.registerBeanFactory(TEST_FACTORY, new TestBeanFactory());
TestBeanDeclaration data = setUpBeanDeclaration();
data.setBeanFactoryName(TEST_FACTORY);
data.setBeanClassName("non.existing.ClassName");
try
{
BeanHelper.createBean(data, null);
fail("Could create bean of an unexisting class!");
}
catch (ConfigurationRuntimeException cex)
{
// ok
}
}
/**
* Tests creating a bean using the default bean factory.
*/
public void testCreateBeanWithDefaultFactory()
{
BeanHelper.setDefaultBeanFactory(new TestBeanFactory());
TestBeanDeclaration data = setUpBeanDeclaration();
data.setBeanClassName(TestBean.class.getName());
checkBean((TestBean) BeanHelper.createBean(data, null));
}
/**
* Tests creating a bean using a non registered factory.
*/
public void testCreateBeanWithUnknownFactory()
{
TestBeanDeclaration data = setUpBeanDeclaration();
data.setBeanFactoryName(TEST_FACTORY);
data.setBeanClassName(TestBean.class.getName());
try
{
BeanHelper.createBean(data, null);
fail("Could create bean with non registered factory!");
}
catch (ConfigurationRuntimeException cex)
{
// ok
}
}
/**
* Tests creating a bean when the factory throws an exception.
*/
public void testCreateBeanWithException()
{
BeanHelper.registerBeanFactory(TEST_FACTORY, new TestBeanFactory());
TestBeanDeclaration data = setUpBeanDeclaration();
data.setBeanFactoryName(TEST_FACTORY);
data.setBeanClassName(getClass().getName());
try
{
BeanHelper.createBean(data, null);
fail("Could create bean of wrong class!");
}
catch (ConfigurationRuntimeException cex)
{
// ok
}
}
/**
* Tests if a parameter is correctly passed to the bean factory.
*/
public void testCreateBeanWithParameter()
{
Object param = new Integer(42);
TestBeanFactory factory = new TestBeanFactory();
BeanHelper.registerBeanFactory(TEST_FACTORY, factory);
TestBeanDeclaration data = setUpBeanDeclaration();
data.setBeanFactoryName(TEST_FACTORY);
data.setBeanClassName(TestBean.class.getName());
checkBean((TestBean) BeanHelper.createBean(data, null, param));
assertSame("Wrong parameter", param, factory.parameter);
}
/**
* Returns an initialized bean declaration.
*
* @return the bean declaration
*/
private TestBeanDeclaration setUpBeanDeclaration()
{
TestBeanDeclaration data = new TestBeanDeclaration();
Map properties = new HashMap();
properties.put("stringValue", "testString");
properties.put("intValue", "42");
data.setBeanProperties(properties);
TestBeanDeclaration buddyData = new TestBeanDeclaration();
Map properties2 = new HashMap();
properties2.put("stringValue", "Another test string");
properties2.put("intValue", new Integer(100));
buddyData.setBeanProperties(properties2);
buddyData.setBeanClassName(TestBean.class.getName());
if (BeanHelper.getDefaultBeanFactory() == null)
{
buddyData.setBeanFactoryName(TEST_FACTORY);
}
Map nested = new HashMap();
nested.put("buddy", buddyData);
data.setNestedBeanDeclarations(nested);
return data;
}
/**
* Tests if the bean was correctly initialized from the data of the test
* bean declaration.
*
* @param bean the bean to be checked
*/
private void checkBean(TestBean bean)
{
assertEquals("Wrong string property", "testString", bean
.getStringValue());
assertEquals("Wrong int property", 42, bean.getIntValue());
TestBean buddy = bean.getBuddy();
assertNotNull("Buddy was not set", buddy);
assertEquals("Wrong string property in buddy", "Another test string",
buddy.getStringValue());
assertEquals("Wrong int property in buddy", 100, buddy.getIntValue());
}
/**
* A simple bean class used for testing creation operations.
*/
public static class TestBean
{
private String stringValue;
private int intValue;
private TestBean buddy;
public TestBean getBuddy()
{
return buddy;
}
public void setBuddy(TestBean buddy)
{
this.buddy = buddy;
}
public int getIntValue()
{
return intValue;
}
public void setIntValue(int intValue)
{
this.intValue = intValue;
}
public String getStringValue()
{
return stringValue;
}
public void setStringValue(String stringValue)
{
this.stringValue = stringValue;
}
}
/**
* An implementation of the BeanFactory interface used for testing. This
* implementation is really simple: If the TestBean class is provided, a new
* instance will be created. Otherwise an exception is thrown.
*/
static class TestBeanFactory implements BeanFactory
{
Object parameter;
boolean supportsDefaultClass;
public Object createBean(Class beanClass, BeanDeclaration data, Object param)
throws Exception
{
parameter = param;
if (TestBean.class.equals(beanClass))
{
TestBean bean = new TestBean();
BeanHelper.initBean(bean, data);
return bean;
}
else
{
throw new IllegalArgumentException("Unsupported class: "
+ beanClass);
}
}
/**
* Returns the default class, but only if the supportsDefaultClass flag
* is set.
*/
public Class getDefaultBeanClass()
{
return supportsDefaultClass ? TestBean.class : null;
}
}
/**
* A test implementation of the BeanDeclaration interface. This
* implementation allows to set the values directly, which should be
* returned by the methods required by the BeanDeclaration interface.
*/
static class TestBeanDeclaration implements BeanDeclaration
{
private String beanClassName;
private String beanFactoryName;
private Object beanFactoryParameter;
private Map beanProperties;
private Map nestedBeanDeclarations;
public String getBeanClassName()
{
return beanClassName;
}
public void setBeanClassName(String beanClassName)
{
this.beanClassName = beanClassName;
}
public String getBeanFactoryName()
{
return beanFactoryName;
}
public void setBeanFactoryName(String beanFactoryName)
{
this.beanFactoryName = beanFactoryName;
}
public Object getBeanFactoryParameter()
{
return beanFactoryParameter;
}
public void setBeanFactoryParameter(Object beanFactoryParameter)
{
this.beanFactoryParameter = beanFactoryParameter;
}
public Map getBeanProperties()
{
return beanProperties;
}
public void setBeanProperties(Map beanProperties)
{
this.beanProperties = beanProperties;
}
public Map getNestedBeanDeclarations()
{
return nestedBeanDeclarations;
}
public void setNestedBeanDeclarations(Map nestedBeanDeclarations)
{
this.nestedBeanDeclarations = nestedBeanDeclarations;
}
}
}